home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / DSUTIL12 / BIN2ASM / BIN2ASM.PAS < prev   
Pascal/Delphi Source File  |  1993-10-28  |  19KB  |  552 lines

  1. {-----------------------------------------------------------------------}
  2. { PROJECT        NON-PROFIT HIGH QUALITY PROFESSIONAL SOFTWARE,  }
  3. {            AVAILABLE FOR ALL WORLD                }
  4. { LIBRARY        SYSTEM UTILITIES                                }
  5. { MODULE        BIN_TO_ASM_CONVERTER                            }
  6. { FILE NAME        BIN2ASM.PAS                    }
  7. { PURPOSE        Convert the binary file to a hex format file.   }
  8. { VERSION        1.30                        }
  9. { DATE            28-Oct-93                    }
  10. { DESIGN        Dmitry Stefankov                }
  11. { IMPLEMENTATION    Dmitry Stefankov                 }
  12. { COMPANY        Freelance Software Engineer            }
  13. { ADDRESS        Isakowskogo str, 4-2-30                }
  14. {            Moscow, 123181                    }
  15. {            USSR                        }
  16. {            Tel. 007 (095) 944-6304                }
  17. { COPYRIGHT NOTICE    Copyright (C) 1987-1993, Dmitry Stefankov    }
  18. { RESTRICTED RIGHTS    AVAILABLE ONLY FOR FREE DISTRIBUTION,           }
  19. {            NOT FOR COMMERCIAL PURPOSE            }
  20. { COMPUTER        IBM PC or compatible                }
  21. { OPERATING SYSTEM    MS/PC-DOS Version 3.30 or higher        }
  22. { COMPILER        Turbo Pascal Version 6.0            }
  23. {                       (Borland International Inc.)  or compatible     }
  24. { ASSEMBLY LANGUAGE    Microsoft MASM 5.10 or compatible               }
  25. { LINKER        Turbo Pascal internal                           }
  26. { ARGUMENTS        <infile>     -   input  stream                  }
  27. {                       <outfile>    -   output stream                  }
  28. {                       <bytes>      -   # of bytes per one line        }
  29. {                       <ascii>      -   switch to indicate ASCII set   }
  30. { RETURN        None                        }
  31. { REQUIRES        None                                            }
  32. { NATURAL LANGUAGE      English Language                                 }
  33. { SPECIAL        None                        }
  34. { DESCRIPTION        1.Read from input stream                        }
  35. {                       2.Write ASM-format  output stream               }
  36. {                       3.If switch present then                        }
  37. {                            add ASCII representation for each line     }
  38. { REVISION HISTORY    Dima Stefankov (DS)                }
  39. {               1.00   04-Jan-92  DS  initilal release        }
  40. {                       1.01   05-Jan-92  DS  added documentation       }
  41. {                       1.02   08-Jan-92  DS  added 'bytes' switch      }
  42. {                       1.03   09-Jan-92  DS  some syntax corrections   }
  43. {                       1.04   10-Jan-92  DS  new read/write algorithms }
  44. {                       1.05   24-Jan-92  DS  some corrections          }
  45. {            1.10   25-Aug-92  DS  updated documention    }
  46. {                       1.20   08-Oct-92  DS  some style corrections    }
  47. {                       1.21   27-Oct-92  DS  some corrections          }
  48. {                       1.22   04-Nov-92  DS  some updates              }
  49. {                       1.23   07-Apr-93  DS  some corrections          }
  50. {                       1.24   20-May-93  DS  some style updates        }
  51. {            1.25   04-Jul-93  DS  updated documentation    }
  52. {            1.30   28-Oct-93  DS  some style updates    }
  53. {-----------------------------------------------------------------------}
  54.  
  55.  
  56. {*======================= PROGRAM HEADER PART ==========================*}
  57.  
  58. PROGRAM   BinaryFileToAssemblerFormatFile;
  59.  
  60.  
  61. {*** other modules ***}
  62. {*USES;*}
  63.  
  64.  
  65. {** switches for compilation **}
  66. {$S-}                {*  stack checking     *}
  67. {$R-}                   {*  range checking     *}
  68. {$M 16384,65536,65536}  {*  memory allocation  *}
  69.  
  70.  
  71. {*========================== CONSTANTS PART ============================*}
  72.  
  73. CONST
  74.      asPurpose                  =       'HexAsmFile Converter';
  75.      asVersion                  =       '1.30';
  76.      asAuthor                   =       'Dima Stefankov';
  77.      asCopyright                =       'Copyright (c) 1987, 1993';
  78.      asProgram            =    'Bin2asm';
  79.      asProgramPrompt            =       asProgram+': ';
  80.      asProgramU            =    'BIN2ASM';
  81.  
  82.      { exit codes }
  83.      errTerminateOK             =     0;
  84.      errBadParmsNumber          =     1;
  85.      errSourceNotFound          =     2;
  86.      errDestDontWrite           =     3;
  87.      errSameNames               =     4;
  88.      errSrcOpenFailed           =     6;
  89.      errDestCreateFailed        =     7;
  90.      errBadBytesValue           =     8;
  91.  
  92.      aPercent100                =     100;
  93.  
  94.      achHexPrefix               =     '$';
  95.      achDosExtMark              =     '.';
  96.      asBlankStr                 =     '';
  97.      asSpaces2                  =     '  ';
  98.      asSpaces5                  =     '     ';
  99.      asInDefExt                 =     'bin';
  100.      asOutDefExt                =     'asm';
  101.  
  102.      aAsciiNone                 =     0;
  103.      aAscii7                    =     1;
  104.      aAscii8                    =     2;
  105.  
  106.      aDefBytesPerLine           =     8;
  107.      aMaxBytesPerLine           =     13;
  108.      achAsciiBit7               =     '7';
  109.      achAsciiBit8               =     '8';
  110.  
  111.      aMaxOnHeap                 =     8192;
  112.      aMaxOutBufSize             =     32768;
  113.  
  114.      achNULL                    =     #0;
  115.      achHTAB                    =     #9;
  116.      achCR                      =     #13;
  117.      achZero                    =     '0';
  118.      achSkip                    =     '.';
  119.      achDelimiter               =     ',';
  120.      achSemicolon               =     ';';
  121.  
  122.      achYes                     =     'Y';
  123.      achNo                      =     'N';
  124.  
  125.      achHexSuffix               =     'h';
  126.      asAsmDataDefine            =     'DB';
  127.      asAsmNoList                =     '.XLIST';
  128.      asAsmList                  =     '.LIST';
  129.  
  130.  
  131. {*==================== TYPE DECLARATIONS PART ==========================*}
  132.  
  133. TYPE
  134.     STR3        =       STRING[3];
  135.     STR4        =       STRING[4];
  136.  
  137.  
  138. {*====================== TYPED CONSTANTS PART ==========================*}
  139.  
  140. CONST
  141.  
  142.     setHexChars  :    SET OF System.Char  =  ['0'..'9','A'..'F','a'..'f'];
  143.     setAscii7    :    SET OF System.Char  =  [#32..#126];
  144.     setAscii8    :    SET OF System.Char  =  [#32..#126,#128..#255];
  145.  
  146.      gadbAsciiFormat      :       System.Byte    =  aAsciiNone;
  147.      gadbSymbolsInString  :       System.Byte    =  aDefBytesPerLine;
  148.      gddBytesCountDone    :       System.Longint =  0;
  149.  
  150.  
  151. {*=========================== VARIABLES PART ===========================*}
  152.  
  153. VAR
  154.    gfInputStream        :       FILE;
  155.    gsInFileName         :       STRING[80];
  156.  
  157.    gfOutputFormatText   :       System.Text;
  158.    gfOutputStream       :       FILE  ABSOLUTE  gfOutputFormatText;
  159.    gsOutFileName        :       STRING[80];
  160.  
  161.    gddOffsetInFile      :       System.Longint;
  162.    gddByteCount         :       System.Longint;
  163.    gddInFileSize        :       System.Longint;
  164.  
  165.    gpMemoryBlock        :       System.Pointer;
  166.    gdwMemBlockSize      :       System.Word;
  167.    gdwBytesRead         :       System.Word;
  168.  
  169.    giErrorCode          :       System.Integer;
  170.    gsTempInput          :       STRING;
  171.  
  172.    gdbTextOutBuf        :       ARRAY[1..aMaxOutBufSize] of System.Byte;
  173.  
  174.  
  175.  
  176. {*=========================== FUNCTIONAL PART ==========================*}
  177.  
  178. FUNCTION  _fnbFileExist(VAR fStruc : FILE; sFileName : STRING) : System.Boolean;
  179. {* Check that file exits. *}
  180. VAR
  181.   bResult  :  System.Boolean;
  182.  
  183. BEGIN
  184.   {** attempt to open the file **}
  185.     System.Assign(fStruc,sFileName);
  186.     {$I-}
  187.     System.Reset(fStruc);
  188.     {$I+}
  189.  
  190.   {** copy the result of last I/O operation **}
  191.     bResult := (System.IOResult = 0);
  192.  
  193.     IF (bResult)
  194.       THEN  System.Close(fStruc);
  195.     {if-then}
  196.  
  197.   _fnbFileExist := bResult;
  198. END; { _fnbFileExist }
  199.  
  200.  
  201. FUNCTION  _fnsForceFileNameExt(sFileName, sDefExt : STRING) : STRING;
  202. {* Add extension for filename if not present. *}
  203. BEGIN
  204.    IF (System.Pos(achDosExtMark,sFileName) = 0)
  205.      THEN  sFileName := sFileName + achDosExtMark + sDefExt;
  206.    {if-then}
  207.   _fnsForceFileNameExt := sFileName;
  208. END;
  209. { _fnsForceFileNameExt }
  210.  
  211.  
  212. FUNCTION   _fnchGetFirstChar(sInput : STRING) : System.Char;
  213. {* Returns a first char from string. *}
  214. VAR
  215.   chTemp  :  System.Char;
  216.  
  217. BEGIN
  218.    IF (System.Length(sInput) <> 0)
  219.      THEN  chTemp := sInput[1]
  220.      ELSE  chTemp := achNULL;
  221.    {if-then-else}
  222.   _fnchGetFirstChar := chTemp;
  223. END;
  224. { _fnchGetFirstChar }
  225.  
  226.  
  227. FUNCTION   _fnsByteToAsmFormat(dbInput : System.Byte) : STR4;
  228. {* Converts a byte to the ASM format number representation. *}
  229. CONST
  230.     dbHexTable : ARRAY[0..15] OF System.Char = '0123456789ABCDEF';
  231.  
  232. BEGIN
  233.   _fnsByteToAsmFormat := achZero +
  234.                          dbHexTable[dbInput SHR 4] +
  235.                          dbHexTable[dbInput AND $0F]+
  236.                          achHexSuffix;
  237. END;  { _fnsByteToAsmFormat }
  238.  
  239.  
  240. FUNCTION  _fnsUpcaseStr(sInput : STRING) : STRING;
  241. {* Make all uppercase. *}
  242. VAR
  243.   dbIndex  :  System.BYTE;
  244.   dbCount  :  System.BYTE;
  245.  
  246. BEGIN
  247.   dbCount := System.Length(sInput);
  248.  
  249.   IF (dbCount <> 0)  THEN
  250.     FOR  dbIndex :=  1  TO  dbCount DO
  251.         sInput[dbIndex] := System.Upcase(sInput[dbIndex]);
  252.     {for-to-do}
  253.   {if-then}
  254.  
  255.    _fnsUpcaseStr := sInput;
  256. END; { _fnsUpcaseStr }
  257.  
  258.  
  259. FUNCTION  _fnsNumToStr3(dwNum : System.Word) : STR3;
  260. {* Convert a numeric value to its string representation. *}
  261. VAR
  262.   sTemp : STR3;
  263.  
  264. BEGIN
  265.    System.Str(dwNum:3,sTemp);
  266.    _fnsNumToStr3 := sTemp;
  267. END;
  268. { _fnsNumToStr3 }
  269.  
  270.  
  271.  
  272. {*=========================== PROCEDURAL PART ==========================*}
  273.  
  274. PROCEDURE    _CopyrightDisplay;
  275. {* Outputs the copyright notice. *}
  276. BEGIN
  277.      System.WriteLn(asPurpose+'  Version '+asVersion+', '+asCopyright+'  '+asAuthor);
  278. END;  { _CopyrightDisplay }
  279.  
  280.  
  281. PROCEDURE  _WriteBufferToDisk(VAR fOutTextFile : System.Text;
  282.                                   pMemBuf : System.Pointer;
  283.                                   dwByteCount : System.Word;
  284.                                   dbAsciiSwitch : System.Byte);
  285. {* Writes the contents of buffer in hexadecimal format to file. *}
  286. VAR
  287.   sOutStr            :  STRING;
  288.   sAsciiStr          :  STRING;
  289.   dwOffsetInBuffer   :  System.Word;
  290.   dbInByte, dbIndex  :  System.Byte;
  291.   dbCountInLine      :  System.Byte;
  292.   chAddChar          :  System.Char;
  293.  
  294.  
  295. BEGIN
  296.   {** initial offset in file buffer **}
  297.     dwOffsetInBuffer := 0;
  298.  
  299.   {** main algorithm **}
  300.   WHILE  (dwByteCount <> 0) DO
  301.   BEGIN
  302.     {** init'd strings **}
  303.       sOutStr   := achHTAB+asAsmDataDefine+achHTAB;
  304.       sAsciiStr := asBlankStr;
  305.  
  306.     {** CASE 1: extract full line **}
  307.     {** CASE 2: extract partial line **}
  308.  
  309.     IF ((dwByteCount DIV gadbSymbolsInString) <> 0)
  310.       THEN  dbCountInLine := gadbSymbolsInString
  311.       ELSE  dbCountInLine := dwByteCount;
  312.     {if-then-else}
  313.  
  314.     BEGIN
  315.              FOR  dbIndex := 1  TO  dbCountInLine  DO
  316.              BEGIN
  317.                dbInByte := System.Mem[System.Seg(pMemBuf^):(System.Ofs(pMemBuf^)+dwOffsetInBuffer)];
  318.                sOutStr := sOutStr + _fnsByteToAsmFormat(dbInByte);
  319.  
  320.                IF  (dbIndex < dbCountInLine)
  321.                  THEN  sOutStr := sOutStr + achDelimiter;
  322.                {if-then}
  323.  
  324.                chAddChar := System.Char(dbInByte);
  325.                CASE  dbAsciiSwitch  OF
  326.                         aAscii7   : IF  (chAddChar IN setAscii7)
  327.                                        THEN  sAsciiStr := sAsciiStr + chAddChar
  328.                                        ELSE  sAsciiStr := sAsciiStr + achSkip;
  329.                         aAscii8   : IF  (chAddChar IN  setAscii8)
  330.                                        THEN  sAsciiStr := sAsciiStr + chAddChar
  331.                                        ELSE  sAsciiStr := sAsciiStr + achSkip;
  332.                END;
  333.                {case-of}
  334.  
  335.                System.Inc(dwOffsetInBuffer);
  336.              END;
  337.              {for-to-do}
  338.  
  339.              IF  (dbAsciiSwitch <> aAsciiNone)
  340.                 THEN  BEGIN
  341.                         FOR dbIndex := 1  TO  (gadbSymbolsInString-dbCountInLine)
  342.                            DO  sOutStr := sOutStr + asSpaces5;
  343.                         {for-to-do}
  344.                         sOutStr := sOutStr + achHTAB + achHTAB +
  345.                                    achSemicolon + asSpaces2 + sAsciiStr;
  346.                       END;
  347.              {if-then}
  348.  
  349.              System.WriteLn(fOutTextFile,sOutStr);
  350.              System.Dec(dwByteCount,dbCountInLine);
  351.     END;
  352.     {begin-end}
  353.   END;
  354.   {while-do}
  355.  
  356. END;  { _WriteBufferToDisk }
  357.  
  358.  
  359.  
  360. {*============================== MAIN PART =============================*}
  361.  
  362. BEGIN
  363.   _CopyrightDisplay;
  364.  
  365.      IF (System.ParamCount < 2) THEN
  366.      BEGIN
  367.           System.WriteLn(asProgramPrompt+'  help screen for you.');
  368.           System.WriteLn('Usage: infile outfile [bytes [ascii]]');
  369.           System.WriteLn('  infile   -  source filename           (def. ext. = '+asInDefExt+')');
  370.           System.WriteLn('  outfile  -  destination filename      (def. ext. = '+asOutDefExt+')');
  371.           System.WriteLn('  bytes    -  number bytes for one line (def. num. = ',aDefBytesPerLine,
  372.                          ', max=',aMaxBytesPerLine,')');
  373.           System.WriteLn('  ascii    -  optional, enable to add ASCII-char string');
  374.           System.WriteLn('                '+achAsciiBit7+' -> 7-bit ASCII format,');
  375.           System.WriteLn('                '+achAsciiBit8+' -> 8-bit ASCII format.');
  376.           System.WriteLn('                       (default = none)');
  377.           System.Halt(errBadParmsNumber);
  378.      END;
  379.      {if-then}
  380.  
  381.  
  382.   {** copy the parameters from command line **}
  383.     gsInFileName  := _fnsUpcaseStr(System.ParamStr(1));
  384.     gsInFileName := _fnsForceFileNameExt(gsInFileName,asInDefExt);
  385.  
  386.     gsOutFileName := _fnsUpcaseStr(System.ParamStr(2));
  387.     gsOutFileName := _fnsForceFileNameExt(gsOutFileName,asOutDefExt);
  388.  
  389.  
  390.   {* may be same names? *}
  391.     IF (gsInFileName = gsOutFileName)  THEN
  392.     BEGIN
  393.       System.WriteLn(asProgramPrompt+'  Unable to use same file as input and as output');
  394.       System.Halt(errSameNames);
  395.     END;
  396.     {if-then}
  397.  
  398.  
  399.   {** source file exists? **}
  400.     IF  NOT(_fnbFileExist(gfInputStream,gsInFileName)) THEN
  401.     BEGIN
  402.       System.WriteLn(asProgramPrompt+' Unable to open file '+gsInFileName);
  403.       System.Halt(errSourceNotFound);
  404.     END;
  405.     {if-then}
  406.  
  407.  
  408.   {** destination file present? **}
  409.   IF (_fnbFileExist(gfOutputStream,gsOutFileName)) THEN
  410.   BEGIN
  411.     System.Write(asProgramPrompt+' Output file '+gsOutFileName+
  412.                  ' already exists. Overwrite? (n/y): ');
  413.     System.ReadLn(gsTempInput);
  414.     IF (System.UpCase(_fnchGetFirstChar(gsTempInput)) <> achYes)
  415.       THEN  System.Halt(errDestDontWrite);
  416.     {if-then}
  417.   END;
  418.   {if-then}
  419.  
  420.  
  421.   {** read the following parameter = bytes switch **}
  422.     IF  (System.ParamCount >= 3) THEN
  423.     BEGIN
  424.          gsTempInput := System.ParamStr(3);
  425.          System.Val(gsTempInput,gadbSymbolsInString,giErrorCode);
  426.          IF  (gadbSymbolsInString = 0) OR (gadbSymbolsInString > aMaxBytesPerLine)
  427.             THEN   BEGIN
  428.                System.WriteLn(asProgramPrompt+' Invalid value for BYTES switch.');
  429.                System.Halt(errBadBytesValue);
  430.                    END;
  431.          {if-then}
  432.     END;
  433.     {if-then}
  434.  
  435.  
  436.   {** read the following parameter = ascii switch **}
  437.     IF  (System.ParamCount >= 4) THEN
  438.     BEGIN
  439.          gsTempInput := System.ParamStr(4);
  440.          CASE  gsTempInput[1] OF
  441.               achAsciiBit7    :  gadbAsciiFormat := aAscii7;
  442.               achAsciiBit8    :  gadbAsciiFormat := aAscii8;
  443.          ELSE
  444.              {**reserved**};
  445.          END;
  446.          {case-of}
  447.     END;
  448.     {if-then}
  449.  
  450.  
  451.  
  452.   {** open the source file **}
  453.     System.Assign(gfInputStream,gsInFileName);
  454.     {$I-}
  455.     System.Reset(gfInputStream,1);
  456.     {$I+}
  457.  
  458.     IF  (System.IoResult <> 0) THEN
  459.     BEGIN
  460.       System.WriteLn(asProgramPrompt+' Unable to open '+gsInFileName);
  461.       System.Halt(errSrcOpenFailed);
  462.     END;
  463.     {if-then}
  464.  
  465.  
  466.   {** create the destination file **}
  467.     System.Assign(gfOutputFormatText,gsOutFileName);
  468.     System.SetTextBuf(gfOutputFormatText,gdbTextOutBuf);
  469.     {$I-}
  470.     System.Rewrite(gfOutputFormatText);
  471.     {$I+}
  472.  
  473.     IF  (System.IoResult <> 0) THEN
  474.     BEGIN
  475.       System.WriteLn(asProgramPrompt+' Unable to create '+gsOutFileName);
  476.       System.Halt(errDestCreateFailed);
  477.     END;
  478.     {if-then}
  479.  
  480.  
  481.   {** get a count of bytes to read. **}
  482.     gddByteCount := System.FileSize(gfInputStream);
  483.     gddInFileSize := gddByteCount;
  484.  
  485.  
  486.   {** get memory on heap **}
  487.     IF  (System.MaxAvail < aMaxOnHeap)
  488.       THEN  gdwMemBlockSize := System.MaxAvail
  489.       ELSE  gdwMemBlockSize := aMaxOnHeap;
  490.     {if-then-else}
  491.     System.GetMem(gpMemoryBlock,gdwMemBlockSize);
  492.  
  493.  
  494.  
  495.   {** write first lines to output stream **}
  496.     System.WriteLn(gfOutputFormatText);
  497.     System.WriteLn(gfOutputFormatText,';  SOURCE FILE:  '+gsInFileName);
  498.     System.WriteLn(gfOutputFormatText,';  Created by '+asProgram+' utility, '+asCopyright+'  '+asAuthor);
  499.     System.WriteLn(gfOutputFormatText);
  500.     System.WriteLn(gfOutputFormatText,asAsmNoList);
  501.     System.WriteLn(gfOutputFormatText);
  502.  
  503.  
  504.   {** main loop: read_buffer/write_to_text_file **}
  505.     WHILE (gddByteCount <> 0) DO
  506.     BEGIN
  507.         IF  ((gddByteCount DIV gdwMemBlockSize) <> 0)
  508.           THEN  gdwBytesRead :=  gdwMemBlockSize
  509.           ELSE  gdwBytesRead :=  gddByteCount;
  510.         {if-then-else}
  511.         System.Inc(gddBytesCountDone,gdwBytesRead);
  512.  
  513.         BEGIN
  514.                  System.WriteLn(asProgramPrompt+' Reading...');
  515.                  System.BlockRead(gfInputStream,
  516.                                   System.Mem[System.Seg(gpMemoryBlock^):System.Ofs(gpMemoryBlock^)],
  517.                                   gdwBytesRead,
  518.                                   gdwBytesRead);
  519.                  System.WriteLn(asProgramPrompt+' Writing...');
  520.                  _WriteBufferToDisk(gfOutputFormatText,
  521.                                     gpMemoryBlock,
  522.                                     gdwBytesRead,
  523.                                     gadbAsciiFormat);
  524.                  System.Dec(gddByteCount,gdwBytesRead);
  525.                  System.Write(achCR+asProgramPrompt+' Completed ('+
  526.                  _fnsNumToStr3((gddBytesCountDone*aPercent100) DIV gddInFileSize)+'%)');
  527.                  System.WriteLn;
  528.         END;
  529.     END;
  530.     {while-do}
  531.  
  532.  
  533.   {** write last lines to output stream **}
  534.     System.WriteLn(gfOutputFormatText);
  535.     System.WriteLn(gfOutputFormatText,asAsmList);
  536.  
  537.  
  538.   {** free memory on heap **}
  539.     System.FreeMem(gpMemoryBlock,gdwMemBlockSize);
  540.  
  541.  
  542.   {** close all files **}
  543.     System.Close(gfInputStream);
  544.     System.Close(gfOutputFormatText);
  545.  
  546.  
  547.   {** report all done **}
  548.     System.WriteLn(asProgramPrompt+' Done.');
  549.  
  550.   {* System.Halt(errTerminateOk); *}
  551. END.
  552.